# encoding: utf-8
'''
Created on 2014-12-18

@author: revol
'''
from math import *
import re

class Calculator(object):
    '''
    Generate a function using giving formula
    
    '''


    def __init__(self,formula='',*args):
        self._varis='x'
        if args:
            self._varis=args
        self._formula=formula
        if formula:
            self.f=self.generate(self._formula,self._varis)
        self.prepare()
        
        
    def prepare(self):
        pass
    
    @classmethod
    def generate(self,formula,varis=['x',]):
        regex=re.compile(r'\b(\d+\.?\d*)\b') #find individual numbers
        nums=regex.findall(formula)
        for v in set(nums):
            formula=re.sub(r'\b(?<!\.)('+v+r')(?!\.)\b', str(float(v)), formula)
        def f(*args,**kwargs):
            formu=formula
            if args:
                Args=list(args)
                for v in varis:
                    regex=re.compile(r'(?=[^a-z]*)('+v+r')(?=[^a-z]*)') #find variables
                    formu=regex.sub(str(float(Args.pop(0))),formu)
            elif kwargs:
                for v in kwargs:
                    regex=re.compile(r'(?=[^a-z]*)('+v+r')(?=[^a-z]*)') #find variables
                    formu=regex.sub(str(float(kwargs[v])),formu)
            else:
                raise TypeError, "Need at leat 1 argument."
            print formu
            result=eval(formu)
            return result
#         self.f=f
        return f
    
if __name__ == '__main__':
    test=Calculator.generate("sqrt(x)")
    print "result of sqrt(2) is:%f"% test(x=2)
    test=Calculator('x**3+pi')
    print "result of 2**3+pi is:%f"% test.f(2)
    f=Calculator.generate("x**(1/2)+log10(x)+1.0+0.1")
    print "result of 2**(1/2)+log10(2)+1.0+0.1 is:\n%f"% f(2)
    print 2**(1.0/2.0)+log10(2.0)+1.0+0.1
    print e
    f()